using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
using GraphMyCode.Client.AssemblyService;
using GraphMyCode.Client.Scalling;
using GraphMyCode.Client.Utils;
using GraphMyCode.Controls;

namespace GraphMyCode.Client.ViewModels
{
	public class NodeViewModel : ElementViewModel
	{
		private readonly List<EdgeViewModel> inEdges;
		private readonly VertexDto nodeModel;
		private readonly List<EdgeViewModel> outEdges;
		private readonly ScaleEngine scaleEngine;
		private readonly ExportType type;
		private Point centralPoint;

		public NodeViewModel(VertexDto nodeModel, ScaleEngine scaleEngine, ExportType type)
		{
			inEdges = new List<EdgeViewModel>();
			outEdges = new List<EdgeViewModel>();

			Weight = nodeModel.Weight;
			RealColor = ColorConverter.FromString(nodeModel.Color);
			Color = BrushFactory.GetBrush(RealColor);
			Text = nodeModel.Text;
			Shape = nodeModel.Shape;
			Type = nodeModel.Type;

			this.scaleEngine = scaleEngine;
			this.type = type;

			this.nodeModel = nodeModel;

			centralPoint = new Point(nodeModel.X, nodeModel.Y);
		}

		public NodeViewModel(int id, Point centralPoint, double weight, Color color, NodeShape shape, string text, string type)
		{
			inEdges = new List<EdgeViewModel>();
			outEdges = new List<EdgeViewModel>();

			Weight = weight;
			RealColor = ColorConverter.FromString(color.ToString());
			Color = BrushFactory.GetBrush(RealColor);
			Text = text;
			Shape = shape;
			Type = type;

			scaleEngine = new AbsoluteScaleEngine();
			nodeModel = new VertexDto
			            	{
			            		Id = id,
			            		X = centralPoint.X,
			            		Y = centralPoint.Y,
			            		Attributes = new Dictionary<string, string>()
			            	};

			this.centralPoint = new Point(nodeModel.X, nodeModel.Y);
		}

		public int Id
		{
			get { return nodeModel.Id; }
		}

		public Dictionary<string, string> Attributes
		{
			get { return nodeModel.Attributes; }
		}

		public IEnumerable<KeyValuePair<string, string>> VisibleAttributes
		{
			get { return nodeModel.Attributes; }
		}

		public Point CentralPoint
		{
			get { return centralPoint; }
			set
			{
				if (centralPoint != value)
				{
					centralPoint = value;
					OnPropertyChanged("CentralPoint");
				}
			}
		}

		public string ImageName
		{
			get
			{
				switch (type)
				{
					case ExportType.Assembly:
						return "../Resources/Assembly.png";					
					case ExportType.Class:
						return "../Resources/Class1.png";						
					case ExportType.Method:
						return "../Resources/Method.png";												
					default:
						throw new ArgumentOutOfRangeException();
				}
			}
		}

		public string Text
		{
			get;
			private set;

		}

		public Brush Color
		{
			get;
			private set;
		}

		public string Type
		{
			get;
			private set;
		}

		public Color RealColor
		{
			get;
			private set;
		}

		public double Weight
		{
			get;
			private set;
		}

		public double Width
		{
			get { return scaleEngine.GetActualWidth(Weight); }
		}

		public double FontSize
		{
			get { return scaleEngine.GetFontSize(Weight); }
		}

		public NodeShape Shape
		{
			get;
			private set;
		}

		public List<EdgeViewModel> InEdges
		{
			get { return inEdges; }
		}

		public List<EdgeViewModel> OutEdges
		{
			get { return outEdges; }
		}

		public Geometry ShapeGeometry
		{
			get { return CreateGeometry(); }
		}

		private Geometry CreateGeometry()
		{
			switch (Shape)
			{
				case NodeShape.None:
					return null;
				case NodeShape.Box:
					return GeometryFactory.CreateRect(scaleEngine.GetActualWidth(Weight));
				case NodeShape.Ellipse:
					return GeometryFactory.CreateCircle(scaleEngine.GetActualWidth(Weight) / 2);
				default:
					return null;
			}
		}
	}
}